package util

import (
	"game/game-design/util"
	"reflect"
	"strconv"
	"unsafe"
)

func ReflectSetInt(objField reflect.Value, i64 int64) {
	rValue := reflect.ValueOf(i64)
	if objField.CanSet() {
		objField.SetInt(rValue.Interface().(int64))
	} else {
		//当结构体中的属性为非导出时（即小写字母开始的属性）
		unexportField := reflect.NewAt(objField.Type(), unsafe.Pointer(objField.UnsafeAddr())).Elem()
		unexportField.SetInt(rValue.Interface().(int64))
	}
}

func ReflectSetFloat(objField reflect.Value, f64 float64) {
	rValue := reflect.ValueOf(f64)
	if objField.CanSet() {
		objField.SetFloat(rValue.Interface().(float64))
	} else {
		//当结构体中的属性为非导出时（即小写字母开始的属性）
		unexportField := reflect.NewAt(objField.Type(), unsafe.Pointer(objField.UnsafeAddr())).Elem()
		unexportField.SetFloat(rValue.Interface().(float64))
	}
}

func ReflectSetString(objField reflect.Value, str string) {
	rValue := reflect.ValueOf(str)
	if objField.CanSet() {
		objField.SetString(rValue.Interface().(string))
	} else {
		//当结构体中的属性为非导出时（即小写字母开始的属性）
		unexportField := reflect.NewAt(objField.Type(), unsafe.Pointer(objField.UnsafeAddr())).Elem()
		unexportField.SetString(rValue.Interface().(string))
	}
}

func ReflectSetStruct(objField reflect.Value, structValue reflect.Value) {
	rValue := reflect.ValueOf(structValue.Interface())
	if objField.CanSet() {
		objField.Set(rValue.Elem())
	} else {
		//当结构体中的属性为非导出时（即小写字母开始的属性）
		unexportField := reflect.NewAt(objField.Type(), unsafe.Pointer(objField.UnsafeAddr())).Elem()
		unexportField.Set(rValue.Elem())
	}
}

func ReflectSetSlice(objField reflect.Value, structValue reflect.Value) {
	rValue := reflect.ValueOf(structValue.Interface())
	if objField.CanSet() {
		objField.Set(rValue)
	} else {
		//当结构体中的属性为非导出时（即小写字母开始的属性）
		unexportField := reflect.NewAt(objField.Type(), unsafe.Pointer(objField.UnsafeAddr())).Elem()
		unexportField.Set(rValue)
	}
}

func ReflectSetRawValue(objField reflect.Value, value string) {
	if objField.Kind() == reflect.Int32 {
		i32, err := strconv.ParseInt(value, 10, 32)
		if err == nil {
			ReflectSetInt(objField, i32)
		}
	} else if objField.Kind() == reflect.Int64 {
		i64, err := strconv.ParseInt(value, 10, 64)
		if err == nil {
			ReflectSetInt(objField, i64)
		}
	} else if objField.Kind() == reflect.Float32 {
		f32, err := strconv.ParseFloat(value, 32)
		if err == nil {
			ReflectSetFloat(objField, f32)
		}
	} else if objField.Kind() == reflect.String {
		util.ReflectSetString(objField, value)
	}
}
